from espdl import FaceDetector
from jpeg import Decoder, Encoder

decoder = Decoder()
encoder = Encoder(width=320, height=240, pixel_format="RGB888")
face_detector = FaceDetector()

# Capture and process the image
img = open("face.jpg", "rb").read()  # Capture the original image (usually in JPEG format)
framebuffer = decoder.decode(img)  # Convert to RGB888 format
# Convert memoryview to bytearray for modification
framebuffer = bytearray(framebuffer)
# Run face detection
results = face_detector.run(framebuffer)

# Draw bounding box
def draw_rectangle(buffer, width, height, x, y, w, h, feature_points, color=(255, 0, 0)):
    """
    Draw a rectangular border on an RGB888 format image buffer
    :param buffer: Image buffer
    :param width: Image width
    :param height: Image height
    :param x: X coordinate of the top-left corner of the border
    :param y: Y coordinate of the top-left corner of the border
    :param w: Border width
    :param h: Border height
    :param color: Border color (RGB format)
    """
    # Helper function: Set color of a single pixel
    def set_pixel(buffer, width, x, y, color):
        offset = (y * width + x) * 3
        buffer[offset] = color[0]  # R
        buffer[offset + 1] = color[1]  # G
        buffer[offset + 2] = color[2]  # B

    # Helper function: Draw larger dots
    def draw_large_dot(buffer, width, x, y, color, size=3):
        for i in range(x - size, x + size + 1):
            for j in range(y - size, y + size + 1):
                if 0 <= i < width and 0 <= j < height:
                    set_pixel(buffer, width, i, j, color)

    # Draw top border
    for i in range(x, x + w):
        if 0 <= i < width and 0 <= y < height:
            set_pixel(buffer, width, i, y, color)

    # Draw bottom border
    for i in range(x, x + w):
        if 0 <= i < width and 0 <= y + h < height:
            set_pixel(buffer, width, i, y + h, color)

    # Draw left border
    for j in range(y, y + h):
        if 0 <= j < height and 0 <= x < width:
            set_pixel(buffer, width, x, j, color)

    # Draw right border
    for j in range(y, y + h):
        if 0 <= j < height and 0 <= x + w < width:
            set_pixel(buffer, width, x + w, j, color)

    # Draw feature points
    if feature_points:
        draw_large_dot(buffer, width, feature_points[0], feature_points[1], (0, 0, 255), size=2)
        draw_large_dot(buffer, width, feature_points[2], feature_points[3], (0, 0, 255), size=2)
        draw_large_dot(buffer, width, feature_points[4], feature_points[5], (0, 255, 0), size=2)
        draw_large_dot(buffer, width, feature_points[6], feature_points[7], (255, 0, 0), size=2)
        draw_large_dot(buffer, width, feature_points[8], feature_points[9], (255, 0, 0), size=2)

# Draw face borders on the image
for face in results:
    print(face)
    x1, y1, x2, y2 = face['box']
    draw_rectangle(framebuffer, 320, 240, x1, y1, x2 - x1, y2 - y1, face['features'], color=(255, 0, 0))  # Use red border

# Re-encode the image with borders into JPEG format and save
marked_img = encoder.encode(framebuffer)
with open("face_marked.jpg", "wb") as f:
    f.write(marked_img)